{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hashlib\n",
    "import json\n",
    "import uuid\n",
    "from typing import Union, List\n",
    "import chromadb\n",
    "from chromadb.utils import embedding_functions\n",
    "from langchain_community.embeddings import ModelScopeEmbeddings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def deterministic_uuid(content: Union[str, bytes]) -> str:\n",
    "    \"\"\"Creates deterministic UUID on hash value of string or byte content.\n",
    "\n",
    "    Args:\n",
    "        content: String or byte representation of data.\n",
    "\n",
    "    Returns:\n",
    "        UUID of the content.\n",
    "    \"\"\"\n",
    "    if isinstance(content, str):\n",
    "        content_bytes = content.encode(\"utf-8\")\n",
    "    elif isinstance(content, bytes):\n",
    "        content_bytes = content\n",
    "    else:\n",
    "        raise ValueError(f\"Content type {type(content)} not supported !\")\n",
    "\n",
    "    hash_object = hashlib.sha256(content_bytes)\n",
    "    hash_hex = hash_object.hexdigest()\n",
    "    namespace = uuid.UUID(\"00000000-0000-0000-0000-000000000000\")\n",
    "    content_uuid = str(uuid.uuid5(namespace, hash_hex))\n",
    "\n",
    "    return content_uuid\n",
    "\n",
    "default_ef = embedding_functions.DefaultEmbeddingFunction()\n",
    "\n",
    "def generate_embedding(data: str, **kwargs) -> List[float]:\n",
    "    embedding = default_ef([data])\n",
    "    if len(embedding) == 1:\n",
    "        return embedding[0]\n",
    "    return embedding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.embeddings import SparkLLMTextEmbeddings\n",
    "xinhuo_embeddings = SparkLLMTextEmbeddings(\n",
    "    spark_app_id=\"849d9562\",\n",
    "    spark_api_key=\"e33637f01cebee4a4675eb479d77df12\",\n",
    "    spark_api_secret=\"ZmI0NGE5ZGUwNzQwMGZjYWFiYjg4MTIx\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "Expected EmbeddingFunction.__call__ to have the following signature: odict_keys(['self', 'input']), got odict_keys(['args', 'kwargs'])\nPlease see https://docs.trychroma.com/embeddings for details of the EmbeddingFunction interface.\nPlease note the recent change to the EmbeddingFunction interface: https://docs.trychroma.com/migration#migration-to-0416---november-7-2023 \n",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[75], line 3\u001b[0m\n\u001b[0;32m      1\u001b[0m chroma_client \u001b[38;5;241m=\u001b[39m chromadb\u001b[38;5;241m.\u001b[39mPersistentClient(path\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m./db\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m      2\u001b[0m chroma_client\u001b[38;5;241m.\u001b[39mdelete_collection(name\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmy_collection_prompt\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m----> 3\u001b[0m collection \u001b[38;5;241m=\u001b[39m \u001b[43mchroma_client\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_or_create_collection\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmy_collection_prompt\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m{\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mhnsw:space\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mcosine\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m \u001b[49m\u001b[43m}\u001b[49m\u001b[43m,\u001b[49m\u001b[43membedding_function\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mxinhuo_embeddings\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m      4\u001b[0m prompt1\u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcommand\u001b[39m\u001b[38;5;124m\"\u001b[39m:\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m单灯调光/开灯/关灯/打开\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m      5\u001b[0m          \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m\"\u001b[39m:\u001b[38;5;124m\"\"\"\u001b[39m\n\u001b[0;32m      6\u001b[0m \u001b[38;5;124m                你是一个调光助手，请使用以下格式回答问题：\u001b[39m\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m     17\u001b[0m \u001b[38;5;124m                \u001b[39m\u001b[38;5;132;01m{context}\u001b[39;00m\n\u001b[0;32m     18\u001b[0m \u001b[38;5;124m\"\"\"\u001b[39m}\n\u001b[0;32m     20\u001b[0m prompt2\u001b[38;5;241m=\u001b[39m {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcommand\u001b[39m\u001b[38;5;124m\"\u001b[39m:\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m方案生成\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m     21\u001b[0m          \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m\"\u001b[39m:\u001b[38;5;124m\"\"\"\u001b[39m\n\u001b[0;32m     22\u001b[0m \u001b[38;5;124m                你是一个方案生成助手，请使用以下格式回答问题：\u001b[39m\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m     33\u001b[0m \u001b[38;5;124m                \u001b[39m\u001b[38;5;132;01m{context}\u001b[39;00m\n\u001b[0;32m     34\u001b[0m \u001b[38;5;124m\"\"\"\u001b[39m}\n",
      "File \u001b[1;32md:\\Program Files\\Python\\Python311\\Lib\\site-packages\\chromadb\\api\\client.py:237\u001b[0m, in \u001b[0;36mClient.get_or_create_collection\u001b[1;34m(self, name, metadata, embedding_function, data_loader)\u001b[0m\n\u001b[0;32m    227\u001b[0m \u001b[38;5;129m@override\u001b[39m\n\u001b[0;32m    228\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mget_or_create_collection\u001b[39m(\n\u001b[0;32m    229\u001b[0m     \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m    235\u001b[0m     data_loader: Optional[DataLoader[Loadable]] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[0;32m    236\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Collection:\n\u001b[1;32m--> 237\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_server\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_or_create_collection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m    238\u001b[0m \u001b[43m        \u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    239\u001b[0m \u001b[43m        \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    240\u001b[0m \u001b[43m        \u001b[49m\u001b[43membedding_function\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43membedding_function\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    241\u001b[0m \u001b[43m        \u001b[49m\u001b[43mdata_loader\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdata_loader\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    242\u001b[0m \u001b[43m        \u001b[49m\u001b[43mtenant\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtenant\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    243\u001b[0m \u001b[43m        \u001b[49m\u001b[43mdatabase\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdatabase\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    244\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[1;32md:\\Program Files\\Python\\Python311\\Lib\\site-packages\\chromadb\\telemetry\\opentelemetry\\__init__.py:127\u001b[0m, in \u001b[0;36mtrace_method.<locals>.decorator.<locals>.wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m    125\u001b[0m \u001b[38;5;28;01mglobal\u001b[39;00m tracer, granularity\n\u001b[0;32m    126\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m trace_granularity \u001b[38;5;241m<\u001b[39m granularity:\n\u001b[1;32m--> 127\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mf\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m    128\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m tracer:\n\u001b[0;32m    129\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m f(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
      "File \u001b[1;32md:\\Program Files\\Python\\Python311\\Lib\\site-packages\\chromadb\\api\\segment.py:217\u001b[0m, in \u001b[0;36mSegmentAPI.get_or_create_collection\u001b[1;34m(self, name, metadata, embedding_function, data_loader, tenant, database)\u001b[0m\n\u001b[0;32m    202\u001b[0m \u001b[38;5;129m@trace_method\u001b[39m(\n\u001b[0;32m    203\u001b[0m     \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSegmentAPI.get_or_create_collection\u001b[39m\u001b[38;5;124m\"\u001b[39m, OpenTelemetryGranularity\u001b[38;5;241m.\u001b[39mOPERATION\n\u001b[0;32m    204\u001b[0m )\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m    215\u001b[0m     database: \u001b[38;5;28mstr\u001b[39m \u001b[38;5;241m=\u001b[39m DEFAULT_DATABASE,\n\u001b[0;32m    216\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Collection:\n\u001b[1;32m--> 217\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate_collection\u001b[49m\u001b[43m(\u001b[49m\u001b[43m  \u001b[49m\u001b[38;5;66;43;03m# type: ignore\u001b[39;49;00m\n\u001b[0;32m    218\u001b[0m \u001b[43m        \u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    219\u001b[0m \u001b[43m        \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    220\u001b[0m \u001b[43m        \u001b[49m\u001b[43membedding_function\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43membedding_function\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    221\u001b[0m \u001b[43m        \u001b[49m\u001b[43mdata_loader\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdata_loader\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    222\u001b[0m \u001b[43m        \u001b[49m\u001b[43mget_or_create\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[0;32m    223\u001b[0m \u001b[43m        \u001b[49m\u001b[43mtenant\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtenant\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    224\u001b[0m \u001b[43m        \u001b[49m\u001b[43mdatabase\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdatabase\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    225\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[1;32md:\\Program Files\\Python\\Python311\\Lib\\site-packages\\chromadb\\telemetry\\opentelemetry\\__init__.py:127\u001b[0m, in \u001b[0;36mtrace_method.<locals>.decorator.<locals>.wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m    125\u001b[0m \u001b[38;5;28;01mglobal\u001b[39;00m tracer, granularity\n\u001b[0;32m    126\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m trace_granularity \u001b[38;5;241m<\u001b[39m granularity:\n\u001b[1;32m--> 127\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mf\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m    128\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m tracer:\n\u001b[0;32m    129\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m f(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n",
      "File \u001b[1;32md:\\Program Files\\Python\\Python311\\Lib\\site-packages\\chromadb\\api\\segment.py:191\u001b[0m, in \u001b[0;36mSegmentAPI.create_collection\u001b[1;34m(self, name, metadata, embedding_function, data_loader, get_or_create, tenant, database)\u001b[0m\n\u001b[0;32m    183\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_product_telemetry_client\u001b[38;5;241m.\u001b[39mcapture(\n\u001b[0;32m    184\u001b[0m     ClientCreateCollectionEvent(\n\u001b[0;32m    185\u001b[0m         collection_uuid\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28mid\u001b[39m),\n\u001b[0;32m    186\u001b[0m         embedding_function\u001b[38;5;241m=\u001b[39membedding_function\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m,\n\u001b[0;32m    187\u001b[0m     )\n\u001b[0;32m    188\u001b[0m )\n\u001b[0;32m    189\u001b[0m add_attributes_to_current_span({\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcollection_uuid\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28mid\u001b[39m)})\n\u001b[1;32m--> 191\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mCollection\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m    192\u001b[0m \u001b[43m    \u001b[49m\u001b[43mclient\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m    193\u001b[0m \u001b[43m    \u001b[49m\u001b[38;5;28;43mid\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcoll\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mid\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    194\u001b[0m \u001b[43m    \u001b[49m\u001b[43mname\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mname\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    195\u001b[0m \u001b[43m    \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcoll\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mmetadata\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m  \u001b[49m\u001b[38;5;66;43;03m# type: ignore\u001b[39;49;00m\n\u001b[0;32m    196\u001b[0m \u001b[43m    \u001b[49m\u001b[43membedding_function\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43membedding_function\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    197\u001b[0m \u001b[43m    \u001b[49m\u001b[43mdata_loader\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdata_loader\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    198\u001b[0m \u001b[43m    \u001b[49m\u001b[43mtenant\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtenant\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    199\u001b[0m \u001b[43m    \u001b[49m\u001b[43mdatabase\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdatabase\u001b[49m\u001b[43m,\u001b[49m\n\u001b[0;32m    200\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[1;32md:\\Program Files\\Python\\Python311\\Lib\\site-packages\\chromadb\\api\\models\\Collection.py:87\u001b[0m, in \u001b[0;36mCollection.__init__\u001b[1;34m(self, client, name, id, embedding_function, data_loader, tenant, database, metadata)\u001b[0m\n\u001b[0;32m     85\u001b[0m \u001b[38;5;66;03m# Check to make sure the embedding function has the right signature, as defined by the EmbeddingFunction protocol\u001b[39;00m\n\u001b[0;32m     86\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m embedding_function \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m---> 87\u001b[0m     \u001b[43mvalidate_embedding_function\u001b[49m\u001b[43m(\u001b[49m\u001b[43membedding_function\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m     89\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_embedding_function \u001b[38;5;241m=\u001b[39m embedding_function\n\u001b[0;32m     90\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_data_loader \u001b[38;5;241m=\u001b[39m data_loader\n",
      "File \u001b[1;32md:\\Program Files\\Python\\Python311\\Lib\\site-packages\\chromadb\\api\\types.py:211\u001b[0m, in \u001b[0;36mvalidate_embedding_function\u001b[1;34m(embedding_function)\u001b[0m\n\u001b[0;32m    208\u001b[0m protocol_signature \u001b[38;5;241m=\u001b[39m signature(EmbeddingFunction\u001b[38;5;241m.\u001b[39m\u001b[38;5;21m__call__\u001b[39m)\u001b[38;5;241m.\u001b[39mparameters\u001b[38;5;241m.\u001b[39mkeys()\n\u001b[0;32m    210\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m function_signature \u001b[38;5;241m==\u001b[39m protocol_signature:\n\u001b[1;32m--> 211\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[0;32m    212\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mExpected EmbeddingFunction.__call__ to have the following signature: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mprotocol_signature\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m, got \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfunction_signature\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    213\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPlease see https://docs.trychroma.com/embeddings for details of the EmbeddingFunction interface.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    214\u001b[0m         \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mPlease note the recent change to the EmbeddingFunction interface: https://docs.trychroma.com/migration#migration-to-0416---november-7-2023 \u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m    215\u001b[0m     )\n",
      "\u001b[1;31mValueError\u001b[0m: Expected EmbeddingFunction.__call__ to have the following signature: odict_keys(['self', 'input']), got odict_keys(['args', 'kwargs'])\nPlease see https://docs.trychroma.com/embeddings for details of the EmbeddingFunction interface.\nPlease note the recent change to the EmbeddingFunction interface: https://docs.trychroma.com/migration#migration-to-0416---november-7-2023 \n"
     ]
    }
   ],
   "source": [
    "chroma_client = chromadb.PersistentClient(path=\"./db\")\n",
    "chroma_client.delete_collection(name=\"my_collection_prompt\")\n",
    "collection = chroma_client.get_or_create_collection(name=\"my_collection_prompt\",metadata={ \"hnsw:space\": \"cosine\" },embedding_function=xinhuo_embeddings)\n",
    "prompt1= {\"command\":\"单灯调光/开灯/关灯/打开\",\n",
    "         \"content\":\"\"\"\n",
    "                你是一个调光助手，请使用以下格式回答问题：\n",
    "                Question：您必须回答的输入问题\n",
    "                Thought：你应该经常考虑该怎么做能获取用户输入的灯杆编号、调光信息\n",
    "                Action：直接回复引导用户输入的问题，能够从用户输入的问题中提取出灯杆编号、调光值（0-100）\n",
    "                Observation：等待用户的输入\n",
    "                ... (this Thought/Action/Observation can be repeated zero or more times)\n",
    "                Thought：我现在知道最后的答案了，最终的回答是一个Json格式{\"code\":\"灯杆编号\",\"dimmingValue\":调光值}  \n",
    "                Final Answer：不要任何解释，直接回复最终答案\n",
    "\n",
    "                Begin!\n",
    "                Question：{query}\n",
    "                {context}\n",
    "\"\"\"}\n",
    "\n",
    "prompt2= {\"command\":\"方案生成\",\n",
    "         \"content\":\"\"\"\n",
    "                你是一个方案生成助手，请使用以下格式回答问题：\n",
    "                Question：您必须回答的输入问题\n",
    "                Thought：你应该经常考虑该怎么做能获取用户输入的灯杆编号、调光信息\n",
    "                Action：直接回复引导用户输入的问题，能够从用户输入的问题中提取出方案信息\n",
    "                Observation：等待用户的输入\n",
    "                ... (this Thought/Action/Observation can be repeated zero or more times)\n",
    "                Thought：我现在知道最后的答案了，最终的回答是一个Json格式\n",
    "                Final Answer：不要任何解释，直接回复最终答案\n",
    "\n",
    "                Begin!\n",
    "                Question：{query}\n",
    "                {context}\n",
    "\"\"\"}\n",
    "\n",
    "\n",
    "json_data1 = json.dumps(prompt1,ensure_ascii=False)\n",
    "print(json_data1)\n",
    "json_data2 = json.dumps(prompt2,ensure_ascii=False)\n",
    "print(json_data2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [],
   "source": [
    "id_1 = deterministic_uuid(json_data1) + \"-prompt\"\n",
    "id_2 = deterministic_uuid(json_data2) + \"-prompt\"\n",
    "collection.upsert(\n",
    "    documents=[json_data1,json_data2],\n",
    "    embeddings=xinhuo_embeddings.embed_documents([json_data1,json_data2]),\n",
    "    ids=[id_1,id_2]\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "查询文档所有数据：{'ids': ['7fb433bc-1467-5fdc-9722-fd6c3b60cc6a-prompt', '9020a97f-1e3a-572c-89ea-fff04d9ac1ba-prompt'], 'embeddings': None, 'metadatas': [None, None], 'documents': ['{\"command\": \"单灯调光/开灯/关灯/打开\", \"content\": \"\\\\n                你是一个调光助手，请使用以下格式回答问题：\\\\n                Question：您必须回答的输入问题\\\\n                Thought：你应该经常考虑该怎么做能获取用户输入的灯杆编号、调光信息\\\\n                Action：直接回复引导用户输入的问题，能够从用户输入的问题中提取出灯杆编号、调光值（0-100）\\\\n                Observation：等待用户的输入\\\\n                ... (this Thought/Action/Observation can be repeated zero or more times)\\\\n                Thought：我现在知道最后的答案了，最终的回答是一个Json格式{\\\\\"code\\\\\":\\\\\"灯杆编号\\\\\",\\\\\"dimmingValue\\\\\":调光值}  \\\\n                Final Answer：不要任何解释，直接回复最终答案\\\\n\\\\n                Begin!\\\\n                Question：{query}\\\\n                {context}\\\\n\"}', '{\"command\": \"方案生成\", \"content\": \"\\\\n                你是一个方案生成助手，请使用以下格式回答问题：\\\\n                Question：您必须回答的输入问题\\\\n                Thought：你应该经常考虑该怎么做能获取用户输入的灯杆编号、调光信息\\\\n                Action：直接回复引导用户输入的问题，能够从用户输入的问题中提取出方案信息\\\\n                Observation：等待用户的输入\\\\n                ... (this Thought/Action/Observation can be repeated zero or more times)\\\\n                Thought：我现在知道最后的答案了，最终的回答是一个Json格式\\\\n                Final Answer：不要任何解释，直接回复最终答案\\\\n\\\\n                Begin!\\\\n                Question：{query}\\\\n                {context}\\\\n\"}'], 'uris': None, 'data': None}\n"
     ]
    }
   ],
   "source": [
    "all_collection = collection.get()\n",
    "print(f\"查询文档所有数据：{all_collection}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_similar_question_sql(question: str, **kwargs) -> list:\n",
    "    # 准备查询条件\n",
    "    where_condition = {\n",
    "    }\n",
    "    query_results = collection.query(query_texts=[question],\n",
    "                                     where=where_condition,\n",
    "                                     n_results=5)\n",
    "    print(f\"查询结果：{query_results}\")\n",
    "    if query_results is None:\n",
    "        return []\n",
    "\n",
    "    print(f\"查询距离：{query_results['distances']}\")\n",
    "    if \"documents\" in query_results:\n",
    "        documents = query_results[\"documents\"]\n",
    "\n",
    "        if len(documents) == 1 and isinstance(documents[0], list):\n",
    "            try:\n",
    "                documents = [json.loads(doc) for doc in documents[0]]\n",
    "            except Exception as e:\n",
    "                return documents[0]\n",
    "\n",
    "        return documents\n",
    "\n",
    "\n",
    "get_similar_question_sql(\"打开灯杆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Number of requested results 5 is greater than number of elements in index 2, updating n_results = 2\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'ids': [['9020a97f-1e3a-572c-89ea-fff04d9ac1ba-prompt',\n",
       "   '7fb433bc-1467-5fdc-9722-fd6c3b60cc6a-prompt']],\n",
       " 'distances': [[0.051265624142551314, 0.05405002125283287]],\n",
       " 'metadatas': [[None, None]],\n",
       " 'embeddings': None,\n",
       " 'documents': [['{\"command\": \"方案生成\", \"content\": \"\\\\n                你是一个方案生成助手，请使用以下格式回答问题：\\\\n                Question：您必须回答的输入问题\\\\n                Thought：你应该经常考虑该怎么做能获取用户输入的灯杆编号、调光信息\\\\n                Action：直接回复引导用户输入的问题，能够从用户输入的问题中提取出方案信息\\\\n                Observation：等待用户的输入\\\\n                ... (this Thought/Action/Observation can be repeated zero or more times)\\\\n                Thought：我现在知道最后的答案了，最终的回答是一个Json格式\\\\n                Final Answer：不要任何解释，直接回复最终答案\\\\n\\\\n                Begin!\\\\n                Question：{query}\\\\n                {context}\\\\n\"}',\n",
       "   '{\"command\": \"单灯调光/开灯/关灯/打开\", \"content\": \"\\\\n                你是一个调光助手，请使用以下格式回答问题：\\\\n                Question：您必须回答的输入问题\\\\n                Thought：你应该经常考虑该怎么做能获取用户输入的灯杆编号、调光信息\\\\n                Action：直接回复引导用户输入的问题，能够从用户输入的问题中提取出灯杆编号、调光值（0-100）\\\\n                Observation：等待用户的输入\\\\n                ... (this Thought/Action/Observation can be repeated zero or more times)\\\\n                Thought：我现在知道最后的答案了，最终的回答是一个Json格式{\\\\\"code\\\\\":\\\\\"灯杆编号\\\\\",\\\\\"dimmingValue\\\\\":调光值}  \\\\n                Final Answer：不要任何解释，直接回复最终答案\\\\n\\\\n                Begin!\\\\n                Question：{query}\\\\n                {context}\\\\n\"}']],\n",
       " 'uris': None,\n",
       " 'data': None}"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "query = xinhuo_embeddings.embed_documents([\"下发方案\"])\n",
    "collection.query(query_embeddings=query, n_results=5)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
